package com.hotai.service.impl;

import com.alibaba.druid.util.HttpClientUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.hotai.comment.dtos.ResponseResult;
import com.hotai.comment.enums.AppHttpCodeEnum;
import com.hotai.comment.pojo.Courseware;
import com.hotai.comment.pojo.CoursewareStudent;
import com.hotai.comment.pojo.UserStudent;
import com.hotai.comment.weixin.WeChetAccessToken;
import com.hotai.mapper.CoursewareMapper;
import com.hotai.mapper.CoursewareStudentMapper;
import com.hotai.mapper.UserStudentMapper;
import com.hotai.service.AccountService;
import com.hotai.service.UserStudentSerivice;
import com.hotai.vo.account.*;
import com.hotai.vo.she.SheBaoList;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.config.WxMpConfigStorage;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

import org.springframework.web.client.RestTemplate;

import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import org.springframework.stereotype.Component;

import java.lang.Object;
import java.util.Arrays;
import java.util.List;


@Service
public class AccountServiceImpl implements AccountService {


    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private UserStudentMapper userStudentMapper;

    @Autowired
    private CoursewareStudentMapper coursewareStudentMapper;

    @Autowired
    private CoursewareMapper coursewareMapper;
    //第三方用户唯一凭证
    private static final String appId = "wxa209cc08c430f9ca";
    //   private  static  final   String  appId="wxe19c053f9caab489";
    //密钥
    private static final String appSecret = "a21c271412f2609d706e0bcc9b0db1b8";
//    private  static  final    String appSecret="5ee7b0a00521aa91448954331d6bff83";

    //公众号token
    private static final String wx_token = "a21c271412f2609d706e0bcc9b0db1b8";

    //微信模板消息template_id
    private static final String wx_template_id = "AAqJFSgAc319eYomRl_UHQq5xlK2U8JM7jdBliz6vCM";


    @Override
    public ResponseResult Jssdkconfig(AccountUrl urll) {
        String url = urll.getUrl();
//        log.info("url:{}",url1);
//        String url = reqJson.getString("url");
//        redisTemplate.delete("wxshare:"+url);
        String signData = redisTemplate.opsForValue().get("wxshare:" + url);
        if (StringUtils.isBlank(signData)) {
            long timeStampSec = System.currentTimeMillis() / 1000;
            String timestamp = String.format("%010d", timeStampSec);
            String nonceStr = getRandomStr(8);
            String[] urls = url.split("#");
            String newUrl = urls[0];
            JSONObject respJson = new JSONObject();
            String[] signArr = new String[]{"url=" + newUrl, "jsapi_ticket=" + getWXJsapiTicket(getWXaccessToken()), "noncestr=" + nonceStr, "timestamp=" + timestamp};
            Arrays.sort(signArr);
            String signStr = StringUtils.join(signArr, "&");
            String resSign = DigestUtils.sha1Hex(signStr);
            respJson.put("appId", appId);
            respJson.put("timestamp", timestamp);
            respJson.put("nonceStr", nonceStr);
            respJson.put("signature", resSign);
            signData = respJson.toString();
            redisTemplate.opsForValue().set("wxshare:" + url, signData, 120, TimeUnit.MINUTES);
            JSONObject jsonObject = JSONObject.parseObject(signData);
            return ResponseResult.okResult(jsonObject);
        }
        JSONObject jsonObject = JSONObject.parseObject(signData);
        return ResponseResult.okResult(jsonObject);
    }

    /**
     * 拉取用户信息
     *
     * @return
     */
    @Override
    public ResponseResult Jssdkconde(String code, Integer id) {
        JSONObject jssdkpull = Jssdkpull(code);
        String token = jssdkpull.getString("access_token");
        String openid = jssdkpull.getString("openid");
        String url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + token + "&openid=" + openid + "&lang=zh_CN";
        String template = restTemplate.getForObject(url, String.class);
        JSONObject jsonObject = JSONObject.parseObject(template);
        UserStudent userStudent = userStudentMapper.selectById(id);
        //保持到数据库
        if (jsonObject != null) {
            String headimgurl = jsonObject.getString("headimgurl");
            userStudent.setImg(headimgurl);
            String nickname = jsonObject.getString("nickname");
            try {
                String nicknam = new String(nickname.getBytes("ISO-8859-1"), "UTF-8");
                userStudent.setNickname(nicknam);
                String openidstu = jsonObject.getString("openid");
                //查询以前opid
                UserStudent userStudent1 = userStudentMapper.selectOne(Wrappers.<UserStudent>lambdaQuery().eq(UserStudent::getOpenid, openidstu));
                if (userStudent1 != null) {
                    userStudent1.setOpenid(null);
                    userStudentMapper.updateById(userStudent1);
                }
                userStudent.setOpenid(openidstu);
                String unionid = jsonObject.getString("unionid");
                if (StringUtils.isNotBlank(unionid)) {
                    userStudent.setUnionid(unionid);
                }
                userStudentMapper.updateById(userStudent);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return ResponseResult.okResult(jsonObject);
    }


    @Override
    public ResponseResult SendWe() {
        List<UserStudent> userStudents = userStudentMapper.selectList(Wrappers.<UserStudent>lambdaQuery().eq(UserStudent::getDeid, 1));
        AccountWarewxPer accountWarewxPer = new AccountWarewxPer();
        accountWarewxPer.setMinDate(minDate(1));
        accountWarewxPer.setPattern(2);
        for (UserStudent userStudent : userStudents) {
            if (userStudent.getOpenid() != null) {
                accountWarewxPer.setId(userStudent.getId());
                Integer count = coursewareStudentMapper.wxbaoWare(accountWarewxPer);
                if (count > 0) {
                    SendWeChatMsg(getToken(), userStudent.getOpenid());
                }
            }
        }
        return ResponseResult.errorResult(AppHttpCodeEnum.PQCG, AppHttpCodeEnum.PQCG.getErrorMessage());

    }

    @Override
    public ResponseResult msgChatWecha() {
        List<UserStudent> userStudents = userStudentMapper.selectList(Wrappers.<UserStudent>lambdaQuery().eq(UserStudent::getDeid, 1));
        for (UserStudent userStudent : userStudents) {
            if (userStudent.getOpenid() != null) {
                AccountWarewxPer accountWarewxPer = new AccountWarewxPer();
                accountWarewxPer.setId(userStudent.getId());
                accountWarewxPer.setMinDate(minDate(7));
//                accountWarewxPer.setPattern(2);
                Integer count = coursewareStudentMapper.wxbaoWare(accountWarewxPer);
                if (count > 0) {
                    SendWeChatM(getToken(), userStudent.getOpenid());
                }
            }
        }
        return ResponseResult.errorResult(AppHttpCodeEnum.PQCG, AppHttpCodeEnum.PQCG.getErrorMessage());
    }


    public String getToken() {
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + appSecret;
        String token = redisTemplate.opsForValue().get("tok:" + url);

        if (StringUtils.isBlank(token)) {
            String tokenJsonStr = doGetPost(url, "GET", null);
            JSONObject tokenJson = JSONObject.parseObject(tokenJsonStr);
            String access_token = tokenJson.getString("access_token");
            redisTemplate.opsForValue().set("tok:" + url, access_token, 70, TimeUnit.MINUTES);
            return access_token;
        }
        return token;
    }

    /**
     * 获取 token
     * openid
     *
     * @return
     */

    public JSONObject Jssdkpull(String code) {
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appId + "&secret=" + appSecret + "&code=" + code + "&grant_type=authorization_code";
        String token = redisTemplate.opsForValue().get("tok:" + url);
        if (StringUtils.isBlank(token)) {
            String template = restTemplate.getForObject(url, String.class);
            JSONObject jsonObject = JSONObject.parseObject(template);
            redisTemplate.opsForValue().set("tok:" + url, template, 100, TimeUnit.MINUTES);
            return jsonObject;
        }
        JSONObject jsonObject = JSONObject.parseObject(token);
        return jsonObject;
    }


    /***
     * 发送消息  报告模板
     *
     * @param token
     */
    public String SendWeChatM(String token, String opid) {
        // 接口地址
        String sendMsgApi = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + token;
        //openId
        String toUser = opid;

        UserStudent userStudent = userStudentMapper.selectOne(Wrappers.<UserStudent>lambdaQuery().eq(UserStudent::getOpenid, opid));
        //消息模板ID
        String template_id = "AAqJFSgAc319eYomRl_UHQq5xlK2U8JM7jdBliz6vCM";
        //整体参数map
        Map<String, Object> paramMap = new HashMap<String, Object>();
        //消息主题显示相关map
        Map<String, Object> dataMap = new HashMap<String, Object>();
        //根据自己的模板定义内容和颜色
        AccountWarewxPer accountWarewxPer = new AccountWarewxPer();
        accountWarewxPer.setId(userStudent.getId());
        accountWarewxPer.setMinDate(minDate(7));

        //多少个
        Integer count = coursewareStudentMapper.wxbaoWare(accountWarewxPer);
        //教学次数
        accountWarewxPer.setPattern(1);
        Integer warecount = coursewareStudentMapper.wxbaoWare(accountWarewxPer);
        if (warecount == null) {
            warecount = 0;
        }
        //评测次数
        accountWarewxPer.setPattern(2);
        Integer pincount = coursewareStudentMapper.wxbaoWare(accountWarewxPer);
        if (pincount == null) {
            pincount = 0;
        }


        //学习时间
//        Date date = coursewareStudentMapper.wxbaoDate(accountWarewxPer);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        //7天前
        String format = sdf.format(minDate(7));
        Date date1 = new Date();
        //当天
        String format1 = sdf.format(date1);

        //学习时长
        Integer time = coursewareStudentMapper.wxbaoTime(accountWarewxPer);

        Integer fne = 0;//分
        Integer miao = 0;
        if (time > 60) {
            fne = time / 60;
            miao = time % 60;
        }
        if (time < 60) {
            miao = time;
        }

        dataMap.put("first", new DataEntity("您有" + 1 + "份天坛VR学习一体机的学习周报告待查收", "#173177"));
        dataMap.put("keyword1", new DataEntity(userStudent.getPhone(), "#173177"));
        dataMap.put("keyword2", new DataEntity("2012231061853", "#173177"));
        dataMap.put("keyword3", new DataEntity(format + "至" + format1, "#173177"));
        dataMap.put("keyword4", new DataEntity("本周完成" + count + "次课程学习，教学模式" + warecount + "次，评测模式" + pincount + "次，学习总用时" + fne + "分" + miao, "#173177"));
        dataMap.put("remark", new DataEntity("点击查看详情", "#173177"));
        paramMap.put("touser", toUser);
        paramMap.put("template_id", template_id);
        paramMap.put("data", dataMap);
        paramMap.put("url", "http://edu-dev.bzszxr.com/#/pages/index/index?id=" + userStudent.getId() + "&type=" + 1);         // 点击模板信息跳转地址
        String post = doGetPost(sendMsgApi, "POST", paramMap);
        return post;
    }


    /***
     * 发送消息  课程模板
     *
     * @param token
     */
    public String SendWeChatMsg(String token, String opid) {
        // 接口地址
        String sendMsgApi = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + token;
        //openId
        String toUser = opid;

        UserStudent userStudent = userStudentMapper.selectOne(Wrappers.<UserStudent>lambdaQuery().eq(UserStudent::getOpenid, opid));
        //消息模板ID
        String template_id = "29_V9C4nDbiaWWGrfFPSmCx7xv-0f11fvWJJIjNn4OY";
        //整体参数map
        Map<String, Object> paramMap = new HashMap<String, Object>();
        //消息主题显示相关map
        Map<String, Object> dataMap = new HashMap<String, Object>();
        //根据自己的模板定义内容和颜色
        AccountWarewxPer accountWarewxPer = new AccountWarewxPer();
        accountWarewxPer.setId(userStudent.getId());
        accountWarewxPer.setMinDate(minDate(1));
        accountWarewxPer.setPattern(2);
        //课程名称
        ArrayList<AccountWarewx> accountWarewx = coursewareStudentMapper.wxbao(accountWarewxPer);

        //多少个
        Integer count = coursewareStudentMapper.wxbaoWare(accountWarewxPer);

        String name = "";
        int i = 0;
        for (AccountWarewx warewx : accountWarewx) {
            if (i == 0) {
                name += warewx.getName();
            } else {
                name += "," + warewx.getName();
            }
            i++;
            if (i == 3) {
                break;
            }
        }

        //学习时间
        Date date = coursewareStudentMapper.wxbaoDate(accountWarewxPer);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String format = sdf.format(date);
        //学习时长
        Integer time = coursewareStudentMapper.wxbaoTime(accountWarewxPer);
        Integer fne = 0;//分
        Integer miao = 0;
        if (time > 60) {
            fne = time / 60;
            miao = time % 60;
        }
        if (time < 60) {
            miao = time;
        }

        dataMap.put("first", new DataEntity("您有" + count + "份天坛学习一体机课程评测报告待查收", "#173177"));
        dataMap.put("keyword1", new DataEntity(userStudent.getNickname(), "#173177"));
        dataMap.put("keyword2", new DataEntity(format, "#173177"));
        dataMap.put("keyword3", new DataEntity(fne + "分" + miao + "秒", "#173177"));
        if (accountWarewx.size() == 1) {
            dataMap.put("keyword4", new DataEntity(name, "#173177"));
        } else {
            dataMap.put("keyword4", new DataEntity(name + "等" + accountWarewx.size() + "个课程", "#173177"));

        }
        dataMap.put("remark", new DataEntity("点击查看详情", "#173177"));
        paramMap.put("touser", toUser);
        paramMap.put("template_id", template_id);
        paramMap.put("data", dataMap);
        paramMap.put("url", "http://edu-dev.bzszxr.com/#/pages/index/index?id=" + userStudent.getId() + "&type=" + 0);         // 点击模板信息跳转地址
        String post = doGetPost(sendMsgApi, "POST", paramMap);
        return post;
    }


    public String SendWeChat(String token, String opid, SheBaoList sheBaoList) {
        // 接口地址
        String sendMsgApi = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + token;

        //openId
        String toUser = opid;

        UserStudent userStudent = userStudentMapper.selectOne(Wrappers.<UserStudent>lambdaQuery().eq(UserStudent::getOpenid, opid));
        Courseware courseware = coursewareMapper.selectById(sheBaoList.getCid());
        //消息模板ID
        String template_id = "29_V9C4nDbiaWWGrfFPSmCx7xv-0f11fvWJJIjNn4OY";
        //整体参数map
        Map<String, Object> paramMap = new HashMap<String, Object>();
        //消息主题显示相关map
        Map<String, Object> dataMap = new HashMap<String, Object>();
        //根据自己的模板定义内容和颜色
        AccountWarewxPer accountWarewxPer = new AccountWarewxPer();
        accountWarewxPer.setId(userStudent.getId());
        accountWarewxPer.setMinDate(minDate(1));
        accountWarewxPer.setPattern(2);

        //学习时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String format = sdf.format(sheBaoList.getTime());
        //学习时长
        Integer time = sheBaoList.getShi();
        Integer fne = 0;//分
        Integer miao = 0;
        if (time > 60) {
            fne = time / 60;
            miao = time % 60;
        }
        if (time < 60) {
            miao = time;
        }

        dataMap.put("first", new DataEntity("您有" + 1 + "份天坛学习一体机课程评测报告待查收", "#173177"));
        dataMap.put("keyword1", new DataEntity(userStudent.getNickname(), "#173177"));
        dataMap.put("keyword2", new DataEntity(format, "#173177"));
        dataMap.put("keyword3", new DataEntity(fne + "分" + miao + "秒", "#173177"));
        dataMap.put("keyword4", new DataEntity(courseware.getName(), "#173177"));

        dataMap.put("remark", new DataEntity("点击查看详情", "#173177"));
        paramMap.put("touser", toUser);
        paramMap.put("template_id", template_id);
        paramMap.put("data", dataMap);
        paramMap.put("url", "http://edu-dev.bzszxr.com/#/pages/index/index?id=" + userStudent.getId() + "&type=" + 0);         // 点击模板信息跳转地址
        String post = doGetPost(sendMsgApi, "POST", paramMap);
        return post;
    }


    public Date minDate(Integer i) {
        //获取当前日期
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
        Date today = new Date();
        String endDate = sdf.format(today); //当前日期
        //获取三十天前日期

        AccountWee accountWee = new AccountWee();
        Calendar theCa = Calendar.getInstance();
        theCa.setTime(today);
        theCa.add(theCa.DATE, -i); //天份
        Date start = theCa.getTime();
        return start;
    }


    /**
     * 调用接口 post
     *
     * @param apiPath
     */
    public String doGetPost(String apiPath, String type, Map<String, Object> paramMap) {
        OutputStreamWriter out = null;
        InputStream is = null;
        String result = null;
        try {
            URL url = new URL(apiPath);// 创建连接
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setUseCaches(false);
            connection.setInstanceFollowRedirects(true);
            connection.setRequestMethod(type); // 设置请求方式
            connection.setRequestProperty("Accept", "application/json"); // 设置接收数据的格式
            connection.setRequestProperty("Content-Type", "application/json"); // 设置发送数据的格式
            connection.connect();
            if (type.equals("POST")) {
                out = new OutputStreamWriter(connection.getOutputStream(), "UTF-8"); // utf-8编码
                out.append(JSON.toJSONString(paramMap));
                out.flush();
                out.close();
            }
            // 读取响应
            is = connection.getInputStream();
            int length = (int) connection.getContentLength();// 获取长度
            if (length != -1) {
                byte[] data = new byte[length];
                byte[] temp = new byte[512];
                int readLen = 0;
                int destPos = 0;
                while ((readLen = is.read(temp)) > 0) {
                    System.arraycopy(temp, 0, data, destPos, readLen);
                    destPos += readLen;
                }
                result = new String(data, "UTF-8"); // utf-8编码
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }


    /**
     * 获取刷新access_token
     *
     * @return
     */
    public ResponseResult getrefresh(String token) {
        String url = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=" + appId + "&grant_type=refresh_token&refresh_token=" + token + "";
        String template = restTemplate.getForObject(url, String.class);
        JSONObject jsonObject = JSONObject.parseObject(template);

        return ResponseResult.okResult(jsonObject);
    }

    /**
     * 获取token
     *
     * @return
     */
    public String getWXaccessToken() {
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + appSecret;
        String resp = restTemplate.getForObject(url, String.class);
        JSONObject resJson = JSONObject.parseObject(resp);
//        log.info("获取token:{}",resJson.toJSONString());
        return resJson.getString("access_token");
    }

    /**
     * 入参为token，返回ticket
     *
     * @param token
     * @return
     */
    public String getWXJsapiTicket(String token) {
        String ticket = null;
        if (StringUtils.isBlank(ticket)) {
            String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + token + "&type=jsapi";
            String resp = restTemplate.getForObject(url, String.class);
            JSONObject resJson = JSONObject.parseObject(resp);
//            log.info("获取ticket:{}",resJson.toJSONString());
            return resJson.getString("ticket");
        }
        return ticket;
    }


    /**
     * 生成随机数
     *
     * @param length
     * @return
     */
    public String getRandomStr(int length) {
        Random random = new Random();
        String result = "";
        for (int i = 0; i < length; i++) {
            result += random.nextInt(length);
        }
        return result;
    }


}
